package com.zhucan.account.domain.aggregate;

import com.zhucan.account.infrastructure.db.entity.AccountPO;
import com.zhucan.account.infrastructure.exception.*;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;

import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import java.math.BigDecimal;
import java.time.LocalDateTime;

/**
 * author: zhuCan
 * date: 2020/8/4 19:53
 * description:
 */
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class Account {

  private Long id;
  private String identityCard;
  private String account;
  private String password;
  private String customerName;
  private String cellphone;
  private String address;
  private String job;
  private Boolean suspend;
  private BigDecimal amount;
  private LocalDateTime createTime;
  private LocalDateTime updateTime;


  // 单次存款限额
  private static final BigDecimal DEPOSIT_OVERRUN_AMOUNT = new BigDecimal(10000);

  // 每日取款总额度
  private static final BigDecimal WITHDRAW_OVERRUN_AMOUNT = new BigDecimal(20000);

  // 单次取款额度
  private static final BigDecimal ONCE_WITHDRAW_OVERRUN_AMOUNT = new BigDecimal(2500);

  public Account(AccountPO po){
    this.id = po.getId();
    this.identityCard = po.getIdentityCard();
    this.account = po.getAccount();
    this.password = po.getPassword();
    this.customerName = po.getCustomerName();
    this.cellphone = po.getCellphone();
    this.address = po.getAddress();
    this.job = po.getJob();
    this.suspend = po.getSuspend();
    this.amount = po.getAmount();
    this.createTime = po.getCreateTime();
    this.updateTime = po.getUpdateTime();
  }

  /**
   * 开户
   *
   */
  public void createAccount() {

    // 新账户设置初始状态
    this.amount = BigDecimal.ZERO;
    this.suspend = Boolean.FALSE;
  }

  /**
   * 设置密码
   *
   * @param password
   */
  public void setPassword(String password) {
    this.password = password;
  }

  /**
   * 冻结
   */
  public void suspend() {
    this.suspend = Boolean.TRUE;
  }

  /**
   * 存钱
   *
   * @param amount
   */
  public void deposit(BigDecimal amount) {
    // 检查账户可用性
    checkAvailability();

    // 判断是否超限
    if (amount.compareTo(DEPOSIT_OVERRUN_AMOUNT) >= 0) {
      throw new AccountDepositOverrunException(DEPOSIT_OVERRUN_AMOUNT);
    }

   this.amount = this.getAmount().add(amount);
  }

  /**
   * 取钱
   *
   * @param amount
   */
  public void withdraw(BigDecimal amount) {
    // 检查账户可用性
    checkAvailability();

    // 判断是否超限
    if (amount.compareTo(ONCE_WITHDRAW_OVERRUN_AMOUNT) >= 0) {
      throw new AccountWithdrawOverrunException(ONCE_WITHDRAW_OVERRUN_AMOUNT);
    }

    // 判断余额是否充足
    if (amount.compareTo(this.amount) > 0) {
      throw new AccountNotSufficientFundsException(this.amount);
    }

    this.amount=this.amount.subtract(amount);
  }

  /**
   * 检查账户可用性
   */
  public void checkAvailability() {

    // 检查 是否完成密码初始化
    if (StringUtils.isBlank(this.password)) {
      throw new AccountNotInitializeException("密码未初始化,请先设置密码");
    }

    // 检查 账户是否冻结
    if (this.suspend) {
      throw new AccountSuspendException();
    }
  }
}
